package net.thick4.context.support;

/**
 * ワイルドカードによるパターンマッチをおこなうクラスです。 
 * 対応しているのは以下の表記です。
 * 
 * <p>
 * <dl>
 * <dt>*</dt>
 * <dd>任意の0文字以上の文字列</dd>
 * <dt>?</dt>
 * <dd>任意の1文字</dd>
 * </dl>
 * </p>
 */
public final class Wildcard {
	
	/**
	 * インスタンス化を防ぐためのプライベート・コンストラクタです。
	 */
	private Wildcard() {
	}
			
	/**
	 * 対象の文字列がワイルドカードを含むパターンと一致するかどうかを 判定して返します。
	 * 
	 * @param wildcard ワイルドカードを含むパターン
	 * @param input マッチする対象の文字列
	 * @return 対象の文字列がワイルドカードを含むパターンと一致するかどうか
	 */
	public static boolean matches(String wildcard, String input) {
		input += '\0';
		wildcard += '\0';

		int N = wildcard.length();
		boolean[] states = null;
		boolean[] old = new boolean[N + 1];
		old[0] = true;

		for (int i = 0; i < input.length(); i++) {
			char c = input.charAt(i);
			states = new boolean[N + 1];
			for (int j = 0; j < N; j++) {
				char p = wildcard.charAt(j);
				if (old[j] && (p == '*'))	{ old[j + 1] = true; 	}
				if (old[j] && (p == c))		{ states[j + 1] = true; }
				if (old[j] && (p == '?'))	{ states[j + 1] = true; }
				if (old[j] && (p == '*'))	{ states[j] = true; }
				if (old[j] && (p == '*'))	{ states[j + 1] = true; }
			}
			old = states;
		}
		return states[N];
	}
	
}
